﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BuildPlannerLib.Enums;
using BuildPlannerLib.PlayerActions;
using BuildPlannerLib.SimEvents;
using BuildPlannerLib.Terran.Buildings;
using BuildPlannerLib.Terran.Enums;
using BuildPlannerLib.Buildings;

namespace BuildPlannerLib.Terran.PlayerActions
{
    // Derived class from Action for a Terran player floating a Command Center to a new base
    public class FloatCC : PlayerAction
    {
        // Field for the base from which the SCV will be taken and the Command Center will be placed
        public Base NewBase;

        // Integer property for the index of the new base
        private int newBaseIndex;
        public int NewBaseIndex
        {
            get { return newBaseIndex; }
            set { newBaseIndex = value; }
        }

        // Field for the Command Center to be moved
        public IndividualCommandCenter CommandCenter;

        // Constructor with parameters for base and build
        public FloatCC(Build build, int newBaseIndex, int timeDuration)
        {
            Build = build;
            NewBaseIndex = newBaseIndex;
            NewBase = Build.Map.Bases.ElementAt(NewBaseIndex);
            TimeDuration = timeDuration;
            Description = "Float CC to new base";
            LongDescription = "Floating an existing Command Center or Orbital Command to new base number " + newBaseIndex + ".";
        }

        // Evaluates whether the player is Terran, whether the base can be taken and whether there is more than one Command Center at the specified base
        public override bool RequirementsFilled()
        {
            CommandCenter commandCenter = Build.Player.MainBuilding as CommandCenter;
            Error = null;

            if (commandCenter == null)
            {
                Error = "This action can only be performed by Terran players.";
                return false;
            }

            if (NewBase.Status != BaseStatus.NotTaken)
            {
                Error = "This base has already been expanded to.";
                return false;
            }

            bool availableMacroCommandCenter = commandCenter.IndividualMainBuildings.Exists(delegate(IndividualMainBuilding i)
            {
                IndividualCommandCenter c = i as IndividualCommandCenter;
                return commandCenter.IndividualMainBuildings.IndexOf(i) != 0
                    && i.AtBase == 0
                    && !c.Floating 
                    && c.UpgradeStatus != CommandCenterUpgrade.UpgradingToPF 
                    && c.UpgradeStatus != CommandCenterUpgrade.PlanetaryFortress;
            });
            if (!availableMacroCommandCenter)
            {
                Error = "No available Command Centers for floating.";
                return false;
            }

            return base.RequirementsFilled();
        }

        // Evaluates if the Command Center or Orbital Command can be moved
        public override bool StartCheck()
        {
            CommandCenter commandCenter = Build.Player.MainBuilding as CommandCenter;
            bool availableMacroCommandCenter = commandCenter.IndividualMainBuildings.Exists(delegate(IndividualMainBuilding i)
            {
                IndividualCommandCenter c = i as IndividualCommandCenter;
                return commandCenter.IndividualMainBuildings.IndexOf(i) != 0
                    && !i.InUse
                    && !c.Floating
                    && i.AtBase == 0
                    && (c.UpgradeStatus == CommandCenterUpgrade.BasicCC || c.UpgradeStatus == CommandCenterUpgrade.OrbitalCommand);
            });
            if (!availableMacroCommandCenter)
                return false;

            return base.StartCheck();
        }

        // Spends the minerals, removes a worker to build the building, starts taking the base, and adds the event for finishing the action
        public override void StartAction()
        {
            CommandCenter commandCenter = Build.Player.MainBuilding as CommandCenter;
            CommandCenter = commandCenter.IndividualMainBuildings.Find(delegate(IndividualMainBuilding i)
            {
                IndividualCommandCenter c = i as IndividualCommandCenter;
                return commandCenter.IndividualMainBuildings.IndexOf(i) != 0
                    && !i.InUse
                    && !c.Floating
                    && i.AtBase == 0
                    && (c.UpgradeStatus == CommandCenterUpgrade.BasicCC || c.UpgradeStatus == CommandCenterUpgrade.OrbitalCommand);
            }) as IndividualCommandCenter;

            base.StartAction();

            CommandCenter.StartFloating();
            NewBase.StartExpansion();
        }

        // Finishes taking the base, resets worker rallys for the Command Center, and makes the Command Center not in-use
        public override void FinishAction()
        {
            base.FinishAction();

            CommandCenter.FinishFloating(Build.Map.Bases.IndexOf(NewBase));
            NewBase.FinishExpansion();
        }
    }
}
